const CryptoJS = require('crypto-js');
function formatTime(time) {
	if (typeof time !== 'number' || time < 0) {
		return time
	}

	var hour = parseInt(time / 3600)
	time = time % 3600
	var minute = parseInt(time / 60)
	time = time % 60
	var second = time

	return ([hour, minute, second]).map(function(n) {
		n = n.toString()
		return n[1] ? n : '0' + n
	}).join(':')
}

function formatLocation(longitude, latitude) {
	if (typeof longitude === 'string' && typeof latitude === 'string') {
		longitude = parseFloat(longitude)
		latitude = parseFloat(latitude)
	}

	longitude = longitude.toFixed(2)
	latitude = latitude.toFixed(2)

	return {
		longitude: longitude.toString().split('.'),
		latitude: latitude.toString().split('.')
	}
}
var dateUtils = {
	UNITS: {
		'年': 31557600000,
		'月': 2629800000,
		'天': 86400000,
		'小时': 3600000,
		'分钟': 60000,
		'秒': 1000
	},
	humanize: function(milliseconds) {
		var humanize = '';
		for (var key in this.UNITS) {
			if (milliseconds >= this.UNITS[key]) {
				humanize = Math.floor(milliseconds / this.UNITS[key]) + key + '前';
				break;
			}
		}
		return humanize || '刚刚';
	},
	format: function(dateStr) {
		var date = this.parse(dateStr)
		var diff = Date.now() - date.getTime();
		if (diff < this.UNITS['天']) {
			return this.humanize(diff);
		}
		var _format = function(number) {
			return (number < 10 ? ('0' + number) : number);
		};
		return date.getFullYear() + '/' + _format(date.getMonth() + 1) + '/' + _format(date.getDay()) + '-' +
			_format(date.getHours()) + ':' + _format(date.getMinutes());
	},
	parse: function(str) { //将"yyyy-mm-dd HH:MM:ss"格式的字符串，转化为一个Date对象
		var a = str.split(/[^0-9]/);
		return new Date(a[0], a[1] - 1, a[2], a[3], a[4], a[5]);
	}
};
/**
 *对Date的扩展，将 Date 转化为指定格式的String
 *月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符，
 *年(y)可以用 1-4 个占位符，毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
 *例子：
 *(new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423
 *(new Date()).Format("yyyy-M-d h:m:s.S")      ==> 2006-7-2 8:9:4.18
 */
Date.prototype.Format = function(fmt) { //author: meizz 
	var o = {
		"M+": this.getMonth() + 1, //月份 
		"d+": this.getDate(), //日 
		"H+": this.getHours(), //小时 
		"m+": this.getMinutes(), //分 
		"s+": this.getSeconds(), //秒 
		"q+": Math.floor((this.getMonth() + 3) / 3), //季度 
		"S": this.getMilliseconds() //毫秒 
	};
	if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
	for (var k in o)
		if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : ((
			"00" + o[
				k]).substr(("" + o[k]).length)));
	return fmt;
}
Array.prototype.indexOf = function(val) {
	for (var i = 0; i < this.length; i++) {
		if (this[i] == val) {
			return i;
		}
	}
	return -1;
}
Array.prototype.remove = function(val) {
	var index = this.indexOf(val);
	if (index > -1) {
		this.splice(index, 1);
	}
}
String.prototype.Trim = function() {
	return this.replace(/(^\s*)|(\s*$)/g, "");
}
String.prototype.LTrim = function() {
	return this.replace(/(^\s*)/g, "");
}
String.prototype.RTrim = function() {
	return this.replace(/(\s*$)/g, "");
}

function formatNumber(n) {
	n = n.toString()
	return n[1] ? n : '0' + n
}

function objectToUrlParams(obj) {
	var str = "";
	for (var key in obj) {
		str += "&" + key + "=" + obj[key];
	}
	return str.substr(1);
}

function isWechatOrQQ() {
	var ua = navigator.userAgent.toLowerCase();
	if (ua.match(/MicroMessenger/i) == "micromessenger" || ua.match(/WeiBo/i) == "weibo") {
		return true;
	} else if (ua.indexOf('mobile mqqbrowser') > -1) {
		return true;
	} else if (ua.indexOf('iphone') > -1 || ua.indexOf('mac') > -1) {
		if (ua.indexOf('qq') > -1) {
			return true;
		}

	}
	return false;
}

function getDate(type) {
	const date = new Date();
	let year = date.getFullYear();
	let month = date.getMonth() + 1;
	let day = date.getDate();
	if (type === 'start') {
		year = year - 60;
	} else if (type === 'end') {
		year = year + 2;
	}
	month = month > 9 ? month : '0' + month;
	day = day > 9 ? day : '0' + day;
	return `${year}-${month}-${day}`;
}

/*获取当前时间*/
function getNowTime() {
	return Math.round(new Date().getTime() / 1000)
}

/*是否H5*/
function isH5() {
	// #ifdef H5
	return true;
	// #endif
	return false;
}

function encryptUin8Array(dataJson, aesKey, Iv) {
	//解析后台返回的数据
	const encrypted = CryptoJS.AES.encrypt(dataJson, aesKey, {
		iv: Iv,
		mode: CryptoJS.mode.CBC,
		padding: CryptoJS.pad.Pkcs7,
	});
	var byteAes = new Uint8Array(encrypted.ciphertext.sigBytes);

	for (var vIndex = 0; vIndex < encrypted.ciphertext.words.length; ++vIndex) {
		var vNumberI = encrypted.ciphertext.words.at(vIndex);
		byteAes[vIndex * 4 + 0] = (vNumberI >> 24) & 0xff; // 获取最高字节
		byteAes[vIndex * 4 + 1] = (vNumberI >> 16) & 0xff; // 获取次高字节
		byteAes[vIndex * 4 + 2] = (vNumberI >> 8) & 0xff; // 获取次低字节
		byteAes[vIndex * 4 + 3] = (vNumberI >> 0) & 0xff; // 获取最低字节
	}
	//位移
	var moveSize = encrypted.ciphertext.sigBytes / 8;
	var byteMove = new Uint8Array(encrypted.ciphertext.sigBytes);
	for (var vIndex = 0; vIndex < encrypted.ciphertext.sigBytes; ++vIndex) {
		var vIndexR = (vIndex + moveSize) % encrypted.ciphertext.sigBytes;
		byteMove[vIndex] = byteAes[vIndexR];
	}
	//位移
	//取反
	for (var vIndex = 0; vIndex < encrypted.ciphertext.sigBytes; ++vIndex) {
		byteMove[vIndex] = 255 - byteMove[vIndex];
	}
	//取反
	//Uint8Array转换 base64
	const base64String = Buffer.from(byteMove).toString('base64');
	convertUin8Array(base64String, aesKey, Iv);
	////Uint8Array转换 base64
	return base64String;
}

function convertUin8Array(data, CryptoJSkey, Iv) {
	//获取数据解密BAES64转Uin8Array
	const uint8Array = Uint8Array.from(atob(data), (c) => c.charCodeAt(0));
	let uint8ArrayLength = uint8Array.length;
	//取反
	var byteqf = new Uint8Array(uint8ArrayLength);
	for (var vIndex = 0; vIndex < uint8ArrayLength; ++vIndex) {
		byteqf[vIndex] = 255 - uint8Array[vIndex]; // 使用 & 0xFF 来确保结果仍然是 Uint8 的范围（0-255）
	}
	//取反

	//位移
	var moveSize = uint8ArrayLength - uint8ArrayLength / 8; //位移多少位
	var byteMove = new Uint8Array(uint8ArrayLength);
	for (var vIndex = 0; vIndex < uint8ArrayLength; ++vIndex) {
		var vIndexR = (vIndex + moveSize) % uint8ArrayLength;
		byteMove[vIndex] = byteqf[vIndexR];
	}
	//位移
	const base64String = Buffer.from(byteMove).toString('base64');

	const encrypted = CryptoJS.AES.decrypt(base64String, CryptoJSkey, {
		iv: Iv,
		mode: CryptoJS.mode.CBC,
		padding: CryptoJS.pad.Pkcs7,
	});
	console.log(JSON.parse(encrypted.toString(CryptoJS.enc.Utf8)))
	return JSON.parse(encrypted.toString(CryptoJS.enc.Utf8));
};


 function generateUUID() {
	if (typeof crypto === 'object') {
		if (typeof crypto.randomUUID === 'function') {
			return crypto.randomUUID();
		}
		if (typeof crypto.getRandomValues === 'function' && typeof Uint8Array === 'function') {
			const callback = (c) => {
				const num = Number(c);
				return (num ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (num / 4)))).toString(16);
			};
			return '10000000-1000-4000-8000-100000000000'.replace(/[018]/g, callback);
		}
	}
	let timestamp = new Date().getTime();
	let performanceNow = (typeof performance !== 'undefined' && performance.now && performance.now() * 1000) || 0;
	return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
		let random = Math.random() * 16;
		if (timestamp > 0) {
			random = (timestamp + random) % 16 | 0;
			timestamp = Math.floor(timestamp / 16);
		} else {
			random = (performanceNow + random) % 16 | 0;
			performanceNow = Math.floor(performanceNow / 16);
		}
		return (c === 'x' ? random : (random & 0x3) | 0x8).toString(16);
	});
};

	// 字符串转32位字节
function crc32S(input) {
		const crcTable = [];
		let crc = 0 ^ -1;

		for (let i = 0; i < 256; i++) {
			let c = i;
			for (let j = 0; j < 8; j++) {
				if (c & 1) {
					c = 0xedb88320 ^ (c >>> 1);
				} else {
					c = c >>> 1;
				}
			}
			crcTable[i] = c;
		}

		for (let i = 0; i < input.length; i++) {
			crc = (crc >>> 8) ^ crcTable[(crc ^ input.charCodeAt(i)) & 0xff];
		}

		let num = (crc ^ -1) >>> 0;
		let numAll = num.toString(16).toUpperCase();
		if (numAll.length < 8) {
			numAll = '0' + numAll;
		}
		console.log(numAll, '?????????');
		return numAll; //
	};

module.exports = {
	formatTime: formatTime,
	formatLocation: formatLocation,
	dateUtils: dateUtils,
	objectToUrlParams: objectToUrlParams,
	isWechatOrQQ: isWechatOrQQ,
	getDate: getDate,
	getNowTime: getNowTime,
	isH5: isH5,
	convertUin8Array: convertUin8Array,
	encryptUin8Array:encryptUin8Array,
	generateUUID:generateUUID,
	crc32S:crc32S,
}